﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GameEngine
{
    public abstract class GameObject
    {
        #region Attributes

        protected Texture2D _spriteSheet;

        protected Vector2 worldLocation;
        protected Vector2 velocity;

        protected bool enabled;
        
        protected Rectangle collisionRectangle;

        protected bool flipped = false;

        protected SpriteEffects _flipped = SpriteEffects.None;
        
        protected float drawDepth = 0.85f;

        protected Dictionary<string, AnimationSequence> animations = new Dictionary<string, AnimationSequence>();
        protected string currentAnimation;

        #endregion

        #region Properties

        /// <summary>
        /// Flipps the animation to the left or right depending on witch direction player is moving
        /// </summary>
        public SpriteEffects Effect
        {
            get 
            {
                return (flipped)? SpriteEffects.FlipHorizontally : SpriteEffects.None;
            }
            
        }

        public Texture2D SpriteSheet
        {
            get { return this._spriteSheet; }
            set { this._spriteSheet = value; }
        }

        public bool Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }

        public Vector2 WorldLocation
        {
            get { return worldLocation; }
            set { worldLocation = value; }
        }

     

        //ska plockas ut till under klasserna eftersom de kan skilja sig från varandra i hur de ska placeras
        public Rectangle CollisionRectangle
        {
            get
            {
                return new Rectangle(
                    (int)worldLocation.X - (collisionRectangle.Width / 2),
                    (int)WorldLocation.Y - (collisionRectangle.Height / 2),
                    collisionRectangle.Width,
                    collisionRectangle.Height);
            }
            set { collisionRectangle = value; }
        }

       
        #endregion

        #region Local Methods

        /// <summary>
        /// Update the current animation that the gameobject is using. If the animation is done the current animation is set to de next animation, 
        /// else it continues throught the iteration.
        /// </summary>
        /// <param name="gameTime">The gametime is used for updating current animation</param>
        private void updateAnimation(GameTime gameTime)
        {
            if (animations.ContainsKey(currentAnimation))
            {
                if (animations[currentAnimation].FinishedAnimation)
                    PlayAnimation(animations[currentAnimation].NextAnimation);                
                else
                    animations[currentAnimation].Update(gameTime);
            }
        }

        #endregion

        #region Public Methods
        
        /// <summary>
        /// Plays target animation from the animation collection
        /// </summary>
        /// <param name="name">The name of target animation</param>
        public void PlayAnimation(string name)
        {
            if (name != null && animations.ContainsKey(name))
            {
                currentAnimation = name;
                animations[name].Play();
            }
        }

        public virtual void Update(GameTime gameTime)
        {
            //if the Game object is not enabled, it shall not be updated and cancels the update
            if (!enabled) return;

            updateAnimation(gameTime);

            WorldLocation += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
            

        }

        public virtual void Draw(SpriteBatch spriteBatch)
        {
            //if the Game object is not enabled, it shall not be drawn and cancels the draw method
            if (!enabled) return;

            if (animations.ContainsKey(currentAnimation))
            {
                spriteBatch.Draw(
                    SpriteSheet,
                    WorldLocation,
                    animations[currentAnimation].FrameRectangle, 
                    Color.White, 
                    0.0f,
                    Vector2.Zero,
                    1,
                    Effect, 
                    drawDepth);
            }
        }

        #endregion
    }
}
